#region Copyright (c) 2003-2005, Luke T. Maxon

/********************************************************************************************************************
'
' Copyright (c) 2003-2005, Luke T. Maxon
' All rights reserved.
'
' Redistribution and use in source and binary forms, with or without modification, are permitted provided
' that the following conditions are met:
'
' * Redistributions of source code must retain the above copyright notice, this list of conditions and the
' 	following disclaimer.
'
' * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
' 	the following disclaimer in the documentation and/or other materials provided with the distribution.
'
' * Neither the name of the author nor the names of its contributors may be used to endorse or
' 	promote products derived from this software without specific prior written permission.
'
' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
' WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
' PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
' ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
' LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
' INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
' OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
' IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'
'*******************************************************************************************************************/

#endregion

//Contributed by: Ian Cooper

using System.Collections;
using System.Windows.Forms;
using System;

namespace SuedeTest.Core {
   public class ListViewTester : ControlTesterGeneric<ListView> {
      public ListViewTester(string name) : base(name) { }

      /// <summary>
      /// Searches for a row in the associated listview that has the following format
      /// SubItem0Text\r\nSubItem1Text\r\n...True|False\r\n
      /// If the item is found, the item is selected or not, depending on the final flag.
      /// A NoSuchControlException is thrown, if no item is found.
      /// </summary>      
      [Runnable("SetSelected")]
      public void SetSelected(string text) {
         string[] subItemText = text.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries);
         bool found = true;

         TheObject.Invoke((MethodInvoker)delegate()
         {
            for (int i = 0; i < TheObject.Items.Count; i++) {
               found = false;
               ListViewItem lvi = TheObject.Items[i];

               if (CheckItemAgainstString (TheObject.Items[i], subItemText)) {
                  found = true;
                  TheObject.Focus();
                  TheObject.Items[i].Selected = bool.Parse(subItemText[subItemText.Length - 1]);
                  break;
               }
            }
            if (!found) {
               throw new NoSuchControlException("Could not find listview subitem " + text);
            }
         });
      }

      /// <summary>
      /// Checks a ListViewItem's subitems' Text-properties against the strings
      /// in subItems.  MUST be run from within the correct synchronization context.
      /// </summary>
      private bool CheckItemAgainstString(ListViewItem lvi, string[] subItems) {
         for (int j = 0; j < lvi.SubItems.Count; j++) {
            //ensure the subitem text doesn't equal "__SKIP__" (or whatever,) 
            //which indicates that we are concerned about its value.
            if (subItems[j] != ListViewDialog.SKIP_VALUE &&
               !lvi.SubItems[j].Text.Equals(subItems[j])) 
            {
               return false;
            }
         }
         return true;
      }

      [Runnable("SetSelectedIndex")]
      private void RunnerSetSelectedInt(string args) {
         string[] parts = args.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries);
         int idx = int.Parse(parts[0]);

         string [] subItems = new string [parts.Length - 1];
         Array.Copy(parts, 1, subItems, 0, parts.Length - 1);

         Exception e = null;

         TheObject.Invoke((MethodInvoker)delegate() 
         {
            if (TheObject.Items.Count > idx) {
               if (CheckItemAgainstString(TheObject.Items[idx], subItems)) {
                  TheObject.Focus();
                  TheObject.Items[idx].Selected = bool.Parse(parts[parts.Length - 1]);
               } else {
                  e = new NoSuchControlException("Could not find listview item at index " + idx);
               }
            } else {
               e = new NoSuchControlException("Could not find listview item at index " + idx);
            }
         });

         if (e != null) {
            throw e;
         }
      }

      [Runnable("SetSelectedIndexOnly")]
      private void RunnerSetSelectedIndexOnly (string args) {
         string[] parts = args.Split(',');

         int idx = int.Parse(parts[0]);
         bool selected = bool.Parse(parts[1]);
         Exception e = null;
         TheObject.Invoke((MethodInvoker)delegate() 
         {
            if (TheObject.Items.Count > idx) {
               TheObject.Focus();
               TheObject.Items[idx].Selected = selected;
            } else {
               e = new NoSuchControlException("No such index for listview item: " + idx);
            }
         });

         if (e != null) {
            throw e;
         }
      }


      [Runnable("ClearSelected")]
      private void RunnerClearSelected(string args) {
         TheObject.Invoke((MethodInvoker)delegate() {
            foreach (ListViewItem item in TheObject.Items) {
               item.Selected = false;
            }
         });
      }
   }
}